package com.chat.biz.service;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chat.api.dto.AuthCodeDTO;
import com.chat.api.dto.LoginDTO;
import com.chat.api.entity.User;
import com.chat.api.enums.RedisCode;
import com.chat.biz.mapper.AuthMapper;
import com.chat.common.exception.CommonException;
import com.chat.common.jwt.JwtUtil;
import com.chat.common.result.ResultEnum;
import com.chat.common.threadLocal.UserContext;
import com.chat.common.utils.VerifyCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Service
public class AuthService extends ServiceImpl<AuthMapper, User> {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private Client client;

    private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    public String login(LoginDTO loginDTO) {

        User user = baseMapper.findByUsername(loginDTO.getUsername());
        if (user == null || !encoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new CommonException(ResultEnum.LOGIN_ERROR.getMsg());
        }
        user.setLastOnlineTime(LocalDateTime.now()); // 更新用户最后登录时间
        baseMapper.updateById(user);
        return JwtUtil.createToken(user.getUserId(),user.getUsername());
    }



    public void register(LoginDTO loginDTO) {
        User user = new User();
        user.setUsername(loginDTO.getUsername());

        user.setPassword(encoder.encode(loginDTO.getPassword()));
        int row = baseMapper.insert(user);
        if (row != 1) {
            throw new CommonException(ResultEnum.USER_REGISTER_FAIL.getMsg());
        }

    }


    public void findpassword(AuthCodeDTO dto) {
        String key = RedisCode.PHONE_CODE.getCode() + dto.getPhone();
        String code = (String) redisTemplate.opsForValue().get(key);
        if(code==null){
            throw new CommonException(ResultEnum.CODE_IS_EXPIRED.getMsg());
        }

        if(!code.equals(dto.getCode())){
            throw new CommonException(ResultEnum.CODE_IS_ERROR.getMsg());
        }
        User user = baseMapper.selectById(UserContext.getUserId().getUserId());
        user.setPassword(encoder.encode(dto.getPassword()));
        baseMapper.updateById(user);
        redisTemplate.delete(key);
        UserContext.clear();
    }
    public void getSmsCode(String phone, String code) {

        SendSmsRequest smsRequest = new SendSmsRequest();
        smsRequest.setPhoneNumbers(phone);
        smsRequest.setSignName("阿里云短信测试");
        smsRequest.setTemplateCode("SMS_154950909");
        smsRequest.setTemplateParam("{\"code\":\"" + code + "\"}");
        try {
            client.sendSms(smsRequest);
        } catch (Exception e) {
            throw new CommonException(ResultEnum.CODE_SEND_FAIL.getMsg());
        }
    }
    public void sendCode(String phone){
        String code = VerifyCodeUtil.codeBuilder(6);
        String key = RedisCode.PHONE_CODE.getCode() + phone;
        Boolean hasKey = redisTemplate.hasKey(key);
        if(hasKey){
            Long expire = redisTemplate.getExpire(key);
            if(Long.parseLong(RedisCode.EXPIRED_TIME.getCode())-expire<Long.parseLong(RedisCode.EXPIRED_TIME.getCode())){
                throw new CommonException(ResultEnum.CODE_IS_FREQUENT.getMsg());
            }
        }//查看验证码两次发送时间是否少于60秒
        getSmsCode(phone, code);
        redisTemplate.opsForValue().set(key,code,Long.parseLong(RedisCode.EXPIRED_TIME.getCode()), TimeUnit.SECONDS);
    }
}
